﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using DBMigrator.Core.DBProviders;
using StructureMap;

namespace DBMigrator.Core.Execution
{
    public class DownMigrationExecutor : IDownMigrationExecutor
    {
        private readonly IMigrationLocator locator;
        private readonly IVersionManager versionManager;
        private readonly IProviderFactory providerFactory;
        
        public DownMigrationExecutor(IMigrationLocator locator, IVersionManager versionManager, 
            IProviderFactory providerFactory)
        {
            this.locator = locator;
            this.versionManager = versionManager;
            this.providerFactory = providerFactory;
        }

        public void ExecuteDownMigrations(DateTime versionToMigrateTo)
        {
            foreach (IExecutableMigration executableMigration in GetMigrationsToExecute(versionToMigrateTo))
            {
                using(var provider = providerFactory.GetProvider(executableMigration.ConnectionName))
                {
                    if (versionManager.IsVersionLoaded(executableMigration.Version, provider))
                    {
                        executableMigration.Migration.Down(provider);
                        versionManager.RemoveVersion(executableMigration.Version, provider);
                    }
                }
            }
        }

        private IEnumerable<IExecutableMigration> GetMigrationsToExecute(DateTime versionToMigrateTo)
        {
            return locator.GetMigrationsSatisfying(m => m.Version > versionToMigrateTo)
                .OrderBy(m => m.Version);
        }
    }
}
